<template>
	<view class="container">
		<view class="link-box" :style="{transform: 'scale(' + scale + ')',height: 100/scale + '%' }">
			<view class="device-module" v-for="device in deviceList" :key="device.id">
				<view class="device-dec">{{device.str}}</view>
				<view class="device-box" :style="{height: device.uheight*48 + 'px'}">
					<image class="model-img" :src="baseUrl + device.imageUrl"></image>
					<view
						:id="port.id"
						class="port-img-box"
						v-for="port in device.devicePortList"
						:key="port.id"
						:style="{ left: port.locationX + 'px', top: port.locationY + 'px', transform: `rotate(${port.direction == 'top' ? 180 : 0}deg)` }"
					>
						<image class="port-img" :src="handlePortImg(port)" mode="widthFix" />
					</view>
				</view>
			</view>
			<view class="line" :style="line" v-for="(line,index) in lineList" :key="index"></view>
		</view>
	</view>
</template>

<script setup>
import { reactive, toRefs, onMounted  } from 'vue';
import { onLoad,onPullDownRefresh } from '@dcloudio/uni-app'
import { getPortLink } from '@/service/device.js';
import config from '@/config.js'; // 配置文件

// 懒加载图片
const getImageUrl = (name) => {
	return `../../static/images/port/${name}.png`;
};

const state = reactive({
	baseUrl: '',
	windowWidth: 0,
	scale:1,
	linkInfo:{},
	deviceList: [],
	activePortList: [],
	edgeList:[], //链接线信息
	lineList:[] //链接线样式信息（长度，位置...）
})
const {baseUrl, scale, deviceList, lineList} = toRefs(state)

onLoad((options) => {
	state.linkInfo = options
	
	handleScale()
})

onMounted(() => {
	//生产环境
	// #ifdef APP
	state.baseUrl = config.base_url;
	// #endif
	// 开发环境，代理
	// #ifndef APP
	state.baseUrl = '/dev-api';
	// #endif
	getLinkDetail()
});

//根据设备尺寸缩放端口图显示比例
const handleScale = () => {
	setTimeout(() => {
		uni.getSystemInfo({
			success: (res) => {
				state.windowWidth = res.windowWidth;
				let paddingWidth = (50 / 375) * state.windowWidth;
				let curWidth = state.windowWidth - paddingWidth; //屏幕宽度减去padding等，计算模型图实际占据宽度
				state.scale = curWidth / 500;
			}
		});
	}, 200);
};

//获取端口链路详情
const getLinkDetail = () => {
	getPortLink({
		deviceType: state.linkInfo.deviceType,
		deviceId: state.linkInfo.deviceId,
		portIndex: state.linkInfo.portIndex
	}).then(res => {
		const linkList = res.data
		state.deviceList = []
		state.activePortList = []
		state.edgeList = []
		let height = 0
		let deviceObj = {}
		//[{左一，右一}，{右一，右二}，{右二，右三}]，设备去重存储，每个设备对应的两个连接端口存储
		for (let i = 0, len = linkList.length; i < len; i++) {
			let curItem = linkList[i]
			let curEdge = [] //当前链接线
			let lDevice = curItem.leftDeviceInfo //链接左设备
			lDevice.portType = lDevice.portType ? lDevice.portType : 1
			//从设备端口列表比对id找到对应端口
			let curLPort = lDevice.devicePortList.find((item) => item.id == curItem.leftDevicePortId)
			//链接左端口信息
			let lPort = {
			  id: curItem.leftDevicePortId,
			  index: curItem.leftDevicePortIndex,
			  isFront: curLPort&&curLPort.type == 1 ? false : true//判断端口正反面,1 成端线端口是背面，其他都是正面
			}
			curItem.leftIsFront = lPort.isFront
			//判断设备，以防反复存储
			if (lDevice.id&&!deviceObj[lDevice.id]) {
				deviceObj[lDevice.id] = lDevice
				state.deviceList.push(lDevice)
				height += 150 //设备对应描述文字所占高度
				//链接线左端口位置信息
				curEdge.push({
					id: curItem.leftDevicePortId,
					left:curLPort.locationX + 8,
					top: height + curLPort.locationY + (lDevice.portType == 1 ? 6 : lDevice.portType == 2 ? 9 : 10),
					leftIsFront:curItem.leftIsFront,
				})
				height+= lDevice.uheight * 48 //设备高度
			}else{
				curEdge.push({id: curItem.leftDevicePortId,left:curLPort.locationX,top: height+ curLPort.locationY,leftIsFront:curItem.leftIsFront})
			}
			deviceObj[lDevice.id].linkPort ? deviceObj[lDevice.id].linkPort.push(lPort) : (deviceObj[lDevice.id].linkPort = [lPort])
			if (curItem.rightDeviceInfo) {
			  let rDevice = curItem.rightDeviceInfo
			  rDevice.portType = rDevice.portType ? rDevice.portType : 1
			  let curRPort = rDevice.devicePortList.find((item) => item.id == curItem.rightDevicePortId)
			  let rPort = {
				id: curItem.rightDevicePortId,
				index: curItem.rightDevicePortIndex,
				isFront: curRPort&&curRPort.type == 1 ? false : true//判断端口正反面,1 成端线端口是背面，其他都是正面
			  }
			  //判断设备，以防反复存储
			  if (rDevice.id&&!deviceObj[rDevice.id]) {
				deviceObj[rDevice.id] = rDevice
				state.deviceList.push(rDevice)
				height += 150 //设备对应描述文字所占高度
				////链接线右端口位置信息，portType不同端口类型不同
				curEdge.push({
					id: curItem.rightDevicePortId,
					left:curRPort.locationX + 8,
					top: height+ curRPort.locationY + (lDevice.portType == 1 ? 6 : lDevice.portType == 2 ? 9 : 10),
				})
				height += rDevice.uheight * 48 //设备高度
			  }else{
				  curEdge.push({id: curItem.rightDevicePortId,left:curRPort.locationX,top: height+ curRPort.locationY})
			  }
			  deviceObj[rDevice.id].linkPort ? deviceObj[rDevice.id].linkPort.push(rPort) : (deviceObj[rDevice.id].linkPort = [rPort])

				//记录所有链接端口，展示不同颜色端口图
			  state.activePortList.push(curItem.leftDevicePortId, curItem.rightDevicePortId)
			}
			state.edgeList.push(curEdge)
		}
		state.activePortList = [...new Set(state.activePortList)]

		createDeviceNode()
		createEdge()
	})
}

//编写设备节点描述信息
const createDeviceNode = () => {
    state.deviceList.forEach((item) => {
      let portStr = ''
      if (item.linkPort) {
        item.linkPort.forEach((port) => {
          portStr += `, 端口编号：${port.index} (${port.isFront ? '正面' : '背面'}) `
        })
      }
      item.str = `所在区域：${item.l1name}/${item.l2name}/${item.l3name}/${item.l4name} , 所属机柜：${item.rackName} \n所属U位：${
        item.unoIndex ? item.unoIndex : item.unoIndexList
      } , 设备名称：${item.name} ${portStr} `
      createPortNode(item)
    })
}

  //创建端口节点
const createPortNode = (row) => {
    let childList = []
    row.devicePortList.forEach((item, index) => {
      item.portType = row.portType ? row.portType : 1
    })
}

//获取端口图
const img = ['RJ45_0', 'LC_0', '', 'FC_0']
const img_active = ['RJ45_1', 'LC_1', '', 'FC_1']
const handlePortImg = (port) => {
    let imgList = state.activePortList.includes(port.id) ? img_active : img
    return getImageUrl(imgList[port.portType - 1])
}

//创建链接线
const createEdge = () => {
	state.lineList = []
    state.edgeList.forEach((edge) => {
      if (edge.length ==2) {
		//直角三角形的两条直角边，计算线倾斜角度
		const x = Math.abs(edge[0].left - edge[1].left)
		const y = Math.abs(edge[0].top - edge[1].top)
		const len = Math.sqrt(x * x + y * y) //连线长度
	
		let deg = (Math.atan2(y, x) * 180) / Math.PI //旋转角度
	
		deg = deg <= -90 ? 360 + deg : deg //修正角度
		deg = edge[1].left > edge[0].left && edge[1].top < edge[0].top ? -deg : deg //修正角度
		//连线坐标
		const lx = (edge[0].left + edge[1].left) / 2
		const ly = (edge[0].top + edge[1].top) / 2

		state.lineList.push({
		  left: `${lx - len / 2}px`,
		  top: `${ly}px`,
		  width: `${len}px`,
		  transform: `rotate(${deg}deg)`,
		  backgroundColor: edge[0].leftIsFront ? '#aaa' : '#4d892f' //正/背面端口连接线，颜色区分
		})
      }
    })
}

 //判断端口正反面,1 成端线端口是背面，其他都是正面
const judgeFront = (id, portList) => {
	let curPort = portList.find((item) => item.id == id)
	if (curPort) {
		return curPort.type == 1 ? false : true
	}
}
</script>

<style lang="scss" scoped>
	.container{
		box-sizing: border-box;
		width: 100%;
		height: 100%;
		// background-color: #F2F7FA;
		padding: 0 50rpx;
		position: relative;
		.link-box{
			padding: 0 0 40rpx 0;
			transform-origin: 0% 0%;
			position: absolute;
			top: 50rpx;
			overflow-y: auto;
		}
		.device-module{
			width: 500px;
			.device-dec{
				width: 100%;
				height: 150px;
				display: flex;
				align-items: flex-end;
				font-size: 20rpx;
			}
			.device-box {
				width: 100%;
				position: relative;
				.model-img {
					width: 100%;
					height: 100%;
				}
				.port-img-box {
					width: 16px;
					position: absolute;
				}
				.port-img {
					display: block;
					width: 100%;
				}
			}
		}
		.line{
			height: 1px;
			position: absolute;
		}
	}
</style>
